// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"github.com/cznic/strutil"
	"godeit/go/parser"
	"io"
	"os"
	"os/exec"
	"path"
	"runtime"
	"strconv"
)

func do(fname string, src []byte, out io.Writer, xgo, gofmt bool) (err error) {
	var file *parser.File
	if file, err = parser.ParsePkgFile(fname, src, xgo); err != nil {
		return
	}

	if err = rewrite(file.Ast); err != nil {
		return
	}

	buf := &bytes.Buffer{}
	if err = file.Str(strutil.IndentFormatter(buf, "\t")); err != nil {
		return
	}

	if gofmt {
		cmd := &exec.Cmd{
			Stderr: os.Stderr,
		}
		if cmd.Path, err = exec.LookPath("gofmt"); err != nil {
			return
		}

		var gofmtin io.WriteCloser
		if gofmtin, err = cmd.StdinPipe(); err != nil {
			return
		}

		var gofmtout io.ReadCloser
		if gofmtout, err = cmd.StdoutPipe(); err != nil {
			return
		}

		if err = cmd.Start(); err != nil {
			return
		}

		defer func() {
			if e := cmd.Wait(); e != nil && err == nil {
				err = e
			}
		}()

		if _, err = buf.WriteTo(gofmtin); err != nil {
			return
		}

		if err = gofmtin.Close(); err != nil {
			return
		}

		buf = &bytes.Buffer{}
		if _, err = buf.ReadFrom(gofmtout); err != nil {
			return
		}
	}

	_, err = out.Write(buf.Bytes())
	return
}

// me reports its calling site as a string.
func me() string {
	_, file, line, ok := runtime.Caller(1)
	if !ok {
		return "???"
	}

	return path.Base(file) + ":" + strconv.Itoa(line)
}
